import random
import json
from typing import Dict, List, Optional, Any, Tuple
from cards.card_examples import create_card, CARD_REGISTRY
from cards.summoner import Summoner
from cards.champion import Champion
from cards.item import Item


class GameState:
    """游戏状态管理类"""
    
    def __init__(self, player1_id: str, player2_id: str):
        self.player1_id = player1_id
        self.player2_id = player2_id
        self.players = [player1_id, player2_id]
        
        # 游戏阶段
        self.game_phase = "DECK_SELECTION"  # DECK_SELECTION, MULLIGAN, PLAYING, ENDED
        self.current_player = None
        self.turn_number = 0
        
        # 卡组选择
        self.deck_selected = {player1_id: None, player2_id: None}
        
        # 双方召唤师
        self.summoners = {
            player1_id: create_card("basic_summoner"),
            player2_id: create_card("basic_summoner")
        }
        
        # 双方场地（5个位置）
        self.battlefields = {
            player1_id: [None] * 5,
            player2_id: [None] * 5
        }
        
        # 手牌、抽牌堆、弃牌堆
        self.hands = {player1_id: [], player2_id: []}
        self.draw_piles = {player1_id: [], player2_id: []}
        self.discard_piles = {player1_id: [], player2_id: []}
        
        # PP 系统
        self.current_pp = {player1_id: 0, player2_id: 0}
        self.max_pp = {player1_id: 0, player2_id: 0}
        
        # 换牌阶段
        self.mulligan_cards = {player1_id: [], player2_id: []}
        self.mulligan_completed = {player1_id: False, player2_id: False}
        
        # 后手幸运币
        self.lucky_coin_used = {player1_id: False, player2_id: False}
        
        # 动画事件队列
        self.pending_animations = []
    
    def select_deck(self, player_id: str, deck_name: str) -> Dict[str, Any]:
        """选择卡组"""
        if self.game_phase != "DECK_SELECTION":
            return {"success": False, "error": "Not in deck selection phase"}
        
        if player_id not in self.players:
            return {"success": False, "error": "Invalid player ID"}
        
        # 记录选择
        self.deck_selected[player_id] = deck_name
        
        # 检查是否双方都选择了卡组
        if all(self.deck_selected.values()):
            # 双方都选择了，但不在这里初始化游戏
            # 让 ws_handlers 来处理自定义卡组的初始化
            return {"success": True, "message": "Deck selected, starting mulligan", "all_selected": True}
        else:
            return {"success": True, "message": "Deck selected, waiting for opponent", "all_selected": False}
    
    
    
    def mulligan(self, player_id: str, cards_to_return: List[str]) -> Dict[str, Any]:
        """处理换牌操作"""
        if self.game_phase != "MULLIGAN":
            return {"success": False, "error": "Not in mulligan phase"}
        
        if player_id not in self.players:
            return {"success": False, "error": "Invalid player ID"}
        
        if len(cards_to_return) != 4:
            return {"success": False, "error": "Must select 4 cards to return"}
        
        # 验证选择的牌是否在手牌中
        available_cards = self.mulligan_cards[player_id].copy()
        for card_id in cards_to_return:
            if card_id not in available_cards:
                return {"success": False, "error": f"Card {card_id} not in hand"}
            available_cards.remove(card_id)
        
        # 将选择的牌洗回抽牌堆
        for card_id in cards_to_return:
            self.draw_piles[player_id].append(card_id)
        random.shuffle(self.draw_piles[player_id])
        
        # 剩余4张牌进入手牌
        self.hands[player_id] = available_cards.copy()
        self.mulligan_completed[player_id] = True
        
        # 检查是否双方都完成换牌
        if all(self.mulligan_completed.values()):
            self._start_game()
        
        return {"success": True, "message": "Mulligan complete"}
    
    def _start_game(self):
        """开始游戏"""
        self.game_phase = "PLAYING"
        # 随机决定先后手
        self.current_player = random.choice(self.players)
        self.turn_number = 1
        
        # 确定后手玩家
        second_player = self.player2_id if self.current_player == self.player1_id else self.player1_id
        
        # 后手玩家获得幸运币（如果手牌未满）
        if len(self.hands[second_player]) < 9:
            self.hands[second_player].append("lucky_coin")
        
        # 第一回合PP设置（先手和后手都从1/1开始）
        self.max_pp[self.current_player] = 1
        self.current_pp[self.current_player] = 1
    
    def start_turn(self):
        """开始新回合"""
        if self.game_phase != "PLAYING":
            return
        
        # 增加PP上限（最大10）
        if self.max_pp[self.current_player] < 10:
            self.max_pp[self.current_player] += 1
        
        # 回复PP
        self.current_pp[self.current_player] = self.max_pp[self.current_player]
        
        # 抽牌（手牌上限9张）
        if len(self.hands[self.current_player]) < 9:
            if self.draw_piles[self.current_player]:
                card_id = self.draw_piles[self.current_player].pop(0)
                self.hands[self.current_player].append(card_id)
            elif self.discard_piles[self.current_player]:
                # 抽牌堆为空，将弃牌堆洗入抽牌堆
                self.draw_piles[self.current_player] = self.discard_piles[self.current_player].copy()
                self.discard_piles[self.current_player] = []
                random.shuffle(self.draw_piles[self.current_player])
                if self.draw_piles[self.current_player]:
                    card_id = self.draw_piles[self.current_player].pop(0)
                    self.hands[self.current_player].append(card_id)
        
        # 重置场上单位的攻击状态
        for champion in self.battlefields[self.current_player]:
            if champion:
                champion.start_new_turn()
        
        self.turn_number += 1
    
    def summon_champion(self, player_id: str, card_id: str, position: int, guard_target: Optional[str] = None, effect_target: Optional[str] = None) -> Dict[str, Any]:
        """召唤Champion"""
        if self.game_phase != "PLAYING":
            return {"success": False, "error": "Game not started"}
        
        if player_id != self.current_player:
            return {"success": False, "error": "Not your turn"}
        
        if card_id not in self.hands[player_id]:
            return {"success": False, "error": "Card not in hand"}
        
        if position < 0 or position >= 5:
            return {"success": False, "error": "Invalid position"}
        
        if self.battlefields[player_id][position] is not None:
            return {"success": False, "error": "Position occupied"}
        
        # 创建卡牌实例
        try:
            card = create_card(card_id)
        except ValueError:
            return {"success": False, "error": "Invalid card ID"}
        
        if not isinstance(card, Champion):
            return {"success": False, "error": "Can only summon Champions"}
        
        # 检查PP是否足够
        if self.current_pp[player_id] < card.cost:
            return {"success": False, "error": "Insufficient PP"}
        
        # 生成唯一instance_id
        import uuid
        card.instance_id = f"{player_id}_{position}_{card_id}_{uuid.uuid4().hex[:8]}"
        
        # 特殊处理Guard - 检查所有Guard类型
        guard_cards = ["test_guard", "zhen_ji", "sun_ce", "zhou_yu", "zhang_liang", "hua_mulan", "liu_bei", "lu_ban", "diao_chan", "li_shuwen", "liu_bang"]
        if card_id in guard_cards:
            if not guard_target:
                return {"success": False, "error": "Guard must specify target"}
            
            # 验证守卫目标
            if guard_target == f"{player_id}_summoner":
                if not self.summoners[player_id].is_alive():
                    return {"success": False, "error": "Summoner is dead"}
            else:
                target_champion = self.get_champion_by_instance_id(guard_target)
                if not target_champion or not target_champion.is_alive():
                    return {"success": False, "error": "Guard target not found or dead"}
                
                # Guard不能守卫其他Guard
                if target_champion.card_id in guard_cards:
                    return {"success": False, "error": "Guard cannot protect another Guard"}
        
        # 特殊处理Jing Ke
        if card_id == "jing_ke":
            if not effect_target:
                return {"success": False, "error": "Jing Ke must specify target"}
            
            # 验证效果目标 - JingKe不能选择召唤师
            if effect_target.endswith("_summoner"):
                return {"success": False, "error": "Jing Ke cannot target summoners"}
            else:
                target_champion = self.get_champion_by_instance_id(effect_target)
                if not target_champion or not target_champion.is_alive():
                    return {"success": False, "error": "Target champion not found or dead"}
                
                # 检查是否隐身
                if isinstance(target_champion, Champion) and hasattr(target_champion, 'is_hidden') and target_champion.is_hidden:
                    return {"success": False, "error": "Target is hidden"}
                
                # 检查是否为敌方目标
                target_owner = None
                for pid in self.players:
                    if pid != player_id and target_champion in self.battlefields[pid]:
                        target_owner = pid
                        break
                
                if not target_owner:
                    return {"success": False, "error": "Cannot target friendly units"}
        
        # 特殊处理Xi Shi
        if card_id == "xi_shi":
            if not effect_target:
                return {"success": False, "error": "Xi Shi must specify target"}
            
            # 验证效果目标
            if effect_target.endswith("_summoner"):
                # 检查是否为敌方召唤师
                enemy_id = effect_target.split("_summoner")[0]
                if enemy_id == player_id:
                    return {"success": False, "error": "Cannot target your own summoner"}
                target = self.get_summoner(enemy_id)
                if not target or not target.is_alive():
                    return {"success": False, "error": "Target summoner not found or dead"}
            else:
                target_champion = self.get_champion_by_instance_id(effect_target)
                if not target_champion or not target_champion.is_alive():
                    return {"success": False, "error": "Target champion not found or dead"}
                
                # 检查是否隐身
                if isinstance(target_champion, Champion) and hasattr(target_champion, 'is_hidden') and target_champion.is_hidden:
                    return {"success": False, "error": "Target is hidden"}
                
                # 检查是否为敌方目标
                target_owner = None
                for pid in self.players:
                    if pid != player_id and target_champion in self.battlefields[pid]:
                        target_owner = pid
                        break
                
                if not target_owner:
                    return {"success": False, "error": "Cannot target friendly units"}
        
        # 消耗PP
        self.current_pp[player_id] -= card.cost
        
        # 从手牌移除
        self.hands[player_id].remove(card_id)
        
        # 放置到场地
        card.position = position
        self.battlefields[player_id][position] = card
        
        # 设置Guard守卫
        if guard_target:
            card.set_guard(guard_target)
        
        # 触发入场效果
        if hasattr(card, 'on_summon'):
            if card_id in ["jing_ke", "xi_shi"]:
                card.on_summon(self, player_id, effect_target)
            else:
                card.on_summon(self, player_id)
        
        # 添加召唤动画事件
        hand_index = -1
        if card_id in self.hands[player_id]:
            hand_index = self.hands[player_id].index(card_id)
        
        self.add_animation_event('summon', {
            'player_id': player_id,
            'card_id': card_id,
            'position': position,
            'hand_index': hand_index
        })
        
        return {"success": True, "message": f"Successfully summoned {card.name}"}
    
    def use_item(self, player_id: str, card_id: str, target_id: Optional[str] = None) -> Dict[str, Any]:
        """使用Item"""
        if self.game_phase != "PLAYING":
            return {"success": False, "error": "Game not started"}
        
        if player_id != self.current_player:
            return {"success": False, "error": "Not your turn"}
        
        if card_id not in self.hands[player_id]:
            return {"success": False, "error": "Card not in hand"}
        
        # 创建卡牌实例
        try:
            card = create_card(card_id)
        except ValueError:
            return {"success": False, "error": "Invalid card ID"}
        
        if not isinstance(card, Item):
            return {"success": False, "error": "Can only use Items"}
        
        # 检查PP是否足够
        if self.current_pp[player_id] < card.cost:
            return {"success": False, "error": "Insufficient PP"}
        
        # 验证目标（如果是敌方目标，检查是否隐身）
        if card.target_required and target_id and not target_id.endswith("_summoner"):
            # 查找目标champion
            target = self.get_champion_by_instance_id(target_id)
            if target:
                # 检查是否为敌方单位
                target_player = self.get_player_by_champion(target)
                if target_player and target_player != player_id:
                    # 检查是否隐身
                    if isinstance(target, Champion) and hasattr(target, 'is_hidden') and target.is_hidden:
                        return {"success": False, "error": "Target is hidden"}
        
        # 使用物品
        result = card.use(self, player_id, target_id)
        
        if result["success"]:
            # 检查是否需要选择效果（Flag道具）
            if result.get("effect") == "choice_required":
                # 不消耗PP和移除手牌，等待选择
                return result
            
            # 消耗PP
            self.current_pp[player_id] -= card.cost
            
            # 添加物品使用动画事件
            hand_index = -1
            if card_id in self.hands[player_id]:
                hand_index = self.hands[player_id].index(card_id)
            
            self.add_animation_event('use_item', {
                'player_id': player_id,
                'card_id': card_id,
                'target_id': target_id,
                'hand_index': hand_index
            })
            
            # 从手牌移除
            self.hands[player_id].remove(card_id)
            
            # 特殊处理幸运币：使用后不进入弃牌堆（直接消失）
            if card_id == "lucky_coin":
                self.lucky_coin_used[player_id] = True
                # 幸运币不进入弃牌堆
            else:
                # 其他item使用后进入弃牌堆
                self.discard_piles[player_id].append(card_id)
        
        return result
    
    def use_item_with_choice(self, player_id: str, card_id: str, choice_id: str) -> Dict[str, Any]:
        """使用需要选择的道具（如Flag）"""
        if self.game_phase != "PLAYING":
            return {"success": False, "error": "Game not started"}
        
        if player_id != self.current_player:
            return {"success": False, "error": "Not your turn"}
        
        if card_id not in self.hands[player_id]:
            return {"success": False, "error": "Card not in hand"}
        
        # 创建卡牌实例
        try:
            card = create_card(card_id)
        except ValueError:
            return {"success": False, "error": "Invalid card ID"}
        
        if not isinstance(card, Item):
            return {"success": False, "error": "Can only use Items"}
        
        # 检查PP是否足够
        if self.current_pp[player_id] < card.cost:
            return {"success": False, "error": "Insufficient PP"}
        
        # 执行选择效果
        if hasattr(card, 'use_with_choice'):
            result = card.use_with_choice(self, player_id, choice_id)
        else:
            return {"success": False, "error": "Card does not support choice"}
        
        if result["success"]:
            # 消耗PP
            self.current_pp[player_id] -= card.cost
            
            # 从手牌移除
            self.hands[player_id].remove(card_id)
            
            # 进入弃牌堆
            self.discard_piles[player_id].append(card_id)
        
        return result
    
    def attack(self, attacker_id: str, target_id: str) -> Dict[str, Any]:
        """处理攻击"""
        if self.game_phase != "PLAYING":
            return {"success": False, "error": "Game not started"}
        
        # 获取攻击者
        attacker = self.get_champion_by_instance_id(attacker_id)
        if not attacker:
            return {"success": False, "error": "Attacker not found"}
        
        if not attacker.can_attack():
            return {"success": False, "error": "Unit cannot attack"}
        
        # 获取攻击者所属玩家
        attacker_player = self.get_player_by_champion(attacker)
        if not attacker_player:
            return {"success": False, "error": "Attacker player not found"}
        
        # 获取目标
        target = None
        target_player = None
        if target_id.endswith("_summoner"):
            target_player = target_id.split("_summoner")[0]
            if target_player in self.players:
                target = self.summoners[target_player]
        else:
            # 使用instance_id
            target = self.get_champion_by_instance_id(target_id)
            if target:
                target_player = self.get_player_by_champion(target)
        
        if not target or not target.is_alive():
            return {"success": False, "error": "Target not found or dead"}
        
        # 检查目标是否被守卫
        if self._is_target_guarded(target_id, target_player):
            return {"success": False, "error": "Target is guarded"}
        
        # 检查Assassin隐身
        if isinstance(target, Champion) and hasattr(target, 'is_hidden') and target.is_hidden:
            return {"success": False, "error": "Target is hidden"}
        
        # 执行攻击
        attacker_damage = attacker.attack
        target_damage = target.attack if hasattr(target, 'attack') else 0
        
        # Mage特殊处理：主动攻击时不受反击伤害
        if hasattr(attacker, 'is_mage') and attacker.is_mage:
            target_damage = 0
        
        # 保存卡牌数据用于动画（在伤害之前）
        attacker_card_data = attacker.to_dict() if hasattr(attacker, 'to_dict') else {
            'card_id': attacker.card_id,
            'name': attacker.name
        }
        
        # 保存攻击者位置信息（在伤害之前）
        attacker_pos = self._get_champion_position_for_animation(attacker, attacker_player)
        
        # 保存目标位置信息（在伤害之前，如果目标是champion）
        target_pos = None
        if target and not target_id.endswith("_summoner") and isinstance(target, Champion):
            target_pos = self._get_champion_position_for_animation(target, target_player)
        
        # 同时造成伤害
        attacker_dead = attacker.take_damage(target_damage)
        target_dead = target.take_damage(attacker_damage)
        
        # 触发伤害效果钩子
        if hasattr(attacker, 'on_deal_damage') and attacker_damage > 0:
            attacker.on_deal_damage(self, target, attacker_damage, attacker_player)
        
        # 添加攻击动画事件（在移除之前）
        self.add_animation_event('attack', {
            'attacker_id': attacker.instance_id if hasattr(attacker, 'instance_id') else attacker_id,
            'attacker_card_data': attacker_card_data,  # 传递完整卡牌数据
            'attacker_pos': attacker_pos,  # 传递攻击者位置
            'target_id': target_id,
            'target_pos': target_pos,  # 传递目标位置（如果是champion）
            'attacker_damage': attacker_damage,
            'target_damage': target_damage,
            'attacker_dead': attacker_dead,
            'target_dead': target_dead
        })
        
        # 处理死亡（在发送动画事件之后）
        if attacker_dead:
            self._remove_champion_from_battlefield(attacker)
        
        if target_dead:
            if target_id.endswith("_summoner"):
                # 召唤师死亡
                pass
            else:
                self._remove_champion_from_battlefield(target)
        
        # Assassin攻击后解除隐身
        if hasattr(attacker, 'is_hidden') and attacker.is_hidden and hasattr(attacker, 'attack_target'):
            attacker.attack_target()
        
        # 攻击者本回合不能再攻击
        attacker.can_attack_this_turn = False
        
        return {
            "success": True,
            "attacker_damage": attacker_damage,
            "target_damage": target_damage,
            "attacker_dead": attacker_dead,
            "target_dead": target_dead
        }
    
    def end_turn(self, player_id: str) -> Dict[str, Any]:
        """结束回合"""
        if self.game_phase != "PLAYING":
            return {"success": False, "error": "Game not started"}
        
        if player_id != self.current_player:
            return {"success": False, "error": "Not your turn"}
        
        # 切换玩家
        self.current_player = self.player2_id if self.current_player == self.player1_id else self.player1_id
        
        # 开始新回合
        self.start_turn()
        
        # 检查游戏结束
        game_over_result = self.check_game_over()
        if game_over_result["game_over"]:
            self.game_phase = "ENDED"
        
        return {"success": True, "game_over": game_over_result}
    
    def check_game_over(self) -> Dict[str, Any]:
        """检查游戏是否结束"""
        p1_alive = self.summoners[self.player1_id].is_alive()
        p2_alive = self.summoners[self.player2_id].is_alive()
        
        if not p1_alive and not p2_alive:
            return {"game_over": True, "result": "draw", "message": "Draw"}
        elif not p1_alive:
            return {"game_over": True, "result": "p2_wins", "message": f"{self.player2_id} wins"}
        elif not p2_alive:
            return {"game_over": True, "result": "p1_wins", "message": f"{self.player1_id} wins"}
        else:
            return {"game_over": False}
    
    def _is_target_guarded(self, target_id: str, target_player: str) -> bool:
        """检查目标是否被守卫"""
        # 遍历目标玩家的战场，查找是否有Guard在守卫该目标
        for champion in self.battlefields[target_player]:
            if champion and hasattr(champion, 'guarding_target_id') and champion.guarding_target_id == target_id:
                return True
        return False
    
    def _get_champion_position_for_animation(self, champion: Champion, player_id: str) -> Dict[str, Any]:
        """获取Champion的位置信息用于动画"""
        battlefield = self.battlefields[player_id]
        for i, battlefield_champion in enumerate(battlefield):
            if battlefield_champion == champion:
                # 计算实际存在的champion数量（用于居中）
                champions_count = sum(1 for c in battlefield if c is not None)
                
                # 计算该champion在渲染中的实际索引
                rendered_index = 0
                for j, c in enumerate(battlefield):
                    if c is not None:
                        if j == i:
                            return {
                                'player_id': player_id,
                                'position': i,
                                'rendered_index': rendered_index,
                                'champions_count': champions_count
                            }
                        rendered_index += 1
        
        return None
    
    def _remove_champion_from_battlefield(self, champion: Champion):
        """从场地移除Champion"""
        for player_id in self.players:
            for i, battlefield_champion in enumerate(self.battlefields[player_id]):
                if battlefield_champion == champion:
                    # 触发死亡效果
                    if hasattr(champion, 'on_death'):
                        champion.on_death(self, player_id)
                    
                    self.battlefields[player_id][i] = None
                    self.discard_piles[player_id].append(champion.card_id)
                    return
    
    
    def get_champion_by_instance_id(self, instance_id: str) -> Optional[Champion]:
        """根据instance_id获取Champion（推荐使用）"""
        for player_id in self.players:
            for champion in self.battlefields[player_id]:
                if champion and champion.instance_id == instance_id:
                    return champion
        return None
    
    def get_player_by_champion(self, champion: Champion) -> Optional[str]:
        """根据Champion获取玩家ID"""
        for player_id in self.players:
            for battlefield_champion in self.battlefields[player_id]:
                if battlefield_champion == champion:
                    return player_id
        return None
    
    def get_summoner(self, player_id: str) -> Summoner:
        """获取召唤师"""
        return self.summoners[player_id]
    
    def get_current_pp(self, player_id: str) -> int:
        """获取当前PP"""
        return self.current_pp[player_id]
    
    def add_pp(self, player_id: str, amount: int):
        """增加PP"""
        self.current_pp[player_id] += amount
    
    def _remove_dead_champion(self, champion_id: str):
        """移除死亡的Champion"""
        # 查找并移除死亡的Champion
        for player_id in self.players:
            for i, champion in enumerate(self.battlefields[player_id]):
                if champion and (champion.instance_id == champion_id or champion.card_id == champion_id):
                    # 触发死亡效果
                    if hasattr(champion, 'on_death'):
                        champion.on_death(self, player_id)
                    # 从战场移除
                    self.battlefields[player_id][i] = None
                    # 只有非衍生牌才加入弃牌堆
                    if champion.card_id not in ["sun_ce", "zhou_yu"]:
                        self.discard_piles[player_id].append(champion.card_id)
                    return
    
    @staticmethod
    def get_available_decks() -> List[Dict[str, Any]]:
        """获取所有可用的卡组"""
        import os
        import glob
        
        decks = []
        decks_dir = os.path.join(os.path.dirname(__file__), "decks")
        
        for deck_file in glob.glob(os.path.join(decks_dir, "*.json")):
            try:
                with open(deck_file, "r", encoding="utf-8") as f:
                    deck_data = json.load(f)
                
                deck_name = os.path.splitext(os.path.basename(deck_file))[0]
                decks.append({
                    "name": deck_name,
                    "title": deck_data.get("title", deck_name),
                    "description": deck_data.get("description", "")
                })
            except Exception as e:
                print(f"Failed to load deck {deck_file}: {e}")
        
        return decks
    
    def add_animation_event(self, animation_type: str, data: Dict[str, Any]):
        """添加动画事件到队列"""
        self.pending_animations.append({
            'type': animation_type,
            'data': data
        })
    
    def get_and_clear_animations(self) -> List[Dict[str, Any]]:
        """获取并清空动画队列"""
        animations = self.pending_animations.copy()
        self.pending_animations.clear()
        return animations
    
    def to_dict(self, player_id: str) -> Dict[str, Any]:
        """序列化游戏状态（隐藏对手手牌）"""
        opponent_id = self.player2_id if player_id == self.player1_id else self.player1_id
        
        return {
            "game_phase": self.game_phase,
            "current_player": self.current_player,
            "turn_number": self.turn_number,
            "deck_selected": self.deck_selected[player_id],  # 当前玩家的卡组选择
            "deck_selection_completed": self.deck_selected[player_id] is not None,  # 是否已选择
            "players": {
                player_id: {
                    "summoner": self.summoners[player_id].to_dict(),
                    "hand": [create_card(card_id).to_dict() for card_id in self.hands[player_id]],
                    "battlefield": [champion.to_dict() if champion else None for champion in self.battlefields[player_id]],
                    "current_pp": self.current_pp[player_id],
                    "max_pp": self.max_pp[player_id],
                    "draw_pile_count": len(self.draw_piles[player_id]),
                    "discard_pile_count": len(self.discard_piles[player_id])
                },
                opponent_id: {
                    "summoner": self.summoners[opponent_id].to_dict(),
                    "hand_count": len(self.hands[opponent_id]),
                    "battlefield": [champion.to_dict() if champion else None for champion in self.battlefields[opponent_id]],
                    "current_pp": self.current_pp[opponent_id],
                    "max_pp": self.max_pp[opponent_id],
                    "draw_pile_count": len(self.draw_piles[opponent_id]),
                    "discard_pile_count": len(self.discard_piles[opponent_id])
                }
            },
            "mulligan_cards": self.mulligan_cards[player_id] if self.game_phase == "MULLIGAN" else [],
            "mulligan_completed": self.mulligan_completed[player_id]
        }
